<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='Ext-button-Cycle'>/**
</span> * @class Ext.button.Cycle
 * @extends Ext.button.Split
 * A specialized SplitButton that contains a menu of {@link Ext.menu.CheckItem} elements.  The button automatically
 * cycles through each menu item on click, raising the button's {@link #change} event (or calling the button's
 * {@link #changeHandler} function, if supplied) for the active menu item. Clicking on the arrow section of the
 * button displays the dropdown menu just like a normal SplitButton.  
 * {@img Ext.button.Cycle/Ext.button.Cycle.png Ext.button.Cycle component}
 * Example usage:
 * &lt;pre&gt;&lt;code&gt;
Ext.create('Ext.button.Cycle', {
    showText: true,
    prependText: 'View as ',
    renderTo: Ext.getBody(),
    menu: {
        id: 'view-type-menu',
        items: [{
            text:'text only',
            iconCls:'view-text',
            checked:true
        },{
            text:'HTML',
            iconCls:'view-html'
        }]
    },
    changeHandler:function(cycleBtn, activeItem){
        Ext.Msg.alert('Change View', activeItem.text);
    }
});
&lt;/code&gt;&lt;/pre&gt;
 */
Ext.define('Ext.button.Cycle', {

    /* Begin Definitions */

    alias: 'widget.cycle',

    extend: 'Ext.button.Split',
    alternateClassName: 'Ext.CycleButton',

    /* End Definitions */

<span id='Ext-button-Cycle-cfg-items'>    /**
</span>     * @cfg {Array} items &lt;p&gt;Deprecated as of 4.0. Use the {@link #menu} config instead. All menu items will be created
     * as {@link Ext.menu.CheckItem CheckItem}s.&lt;/p&gt;
     * &lt;p&gt;An array of {@link Ext.menu.CheckItem} &lt;b&gt;config&lt;/b&gt; objects to be used when creating the
     * button's menu items (e.g., {text:'Foo', iconCls:'foo-icon'})
     */
<span id='Ext-button-Cycle-cfg-showText'>    /**
</span>     * @cfg {Boolean} showText True to display the active item's text as the button text (defaults to false).
     * The Button will show its configured {@link #text} if this. config is omitted.
     */
<span id='Ext-button-Cycle-cfg-prependText'>    /**
</span>     * @cfg {String} prependText A static string to prepend before the active item's text when displayed as the
     * button's text (only applies when showText = true, defaults to '')
     */
<span id='Ext-button-Cycle-cfg-changeHandler'>    /**
</span>     * @cfg {Function} changeHandler A callback function that will be invoked each time the active menu
     * item in the button's menu has changed.  If this callback is not supplied, the SplitButton will instead
     * fire the {@link #change} event on active item change.  The changeHandler function will be called with the
     * following argument list: (SplitButton this, Ext.menu.CheckItem item)
     */
<span id='Ext-button-Cycle-cfg-forceIcon'>    /**
</span>     * @cfg {String} forceIcon A css class which sets an image to be used as the static icon for this button.  This
     * icon will always be displayed regardless of which item is selected in the dropdown list.  This overrides the 
     * default behavior of changing the button's icon to match the selected item's icon on change.
     */
<span id='Ext-button-Cycle-property-menu'>    /**
</span>     * @property menu
     * @type Menu
     * The {@link Ext.menu.Menu Menu} object used to display the {@link Ext.menu.CheckItem CheckItems} representing the available choices.
     */

    // private
    getButtonText: function(item) {
        var me = this,
            text = '';

        if (item &amp;&amp; me.showText === true) {
            if (me.prependText) {
                text += me.prependText;
            }
            text += item.text;
            return text;
        }
        return me.text;
    },

<span id='Ext-button-Cycle-method-setActiveItem'>    /**
</span>     * Sets the button's active menu item.
     * @param {Ext.menu.CheckItem} item The item to activate
     * @param {Boolean} suppressEvent True to prevent the button's change event from firing (defaults to false)
     */
    setActiveItem: function(item, suppressEvent) {
        var me = this;

        if (!Ext.isObject(item)) {
            item = me.menu.getComponent(item);
        }
        if (item) {
            if (!me.rendered) {
                me.text = me.getButtonText(item);
                me.iconCls = item.iconCls;
            } else {
                me.setText(me.getButtonText(item));
                me.setIconCls(item.iconCls);
            }
            me.activeItem = item;
            if (!item.checked) {
                item.setChecked(true, false);
            }
            if (me.forceIcon) {
                me.setIconCls(me.forceIcon);
            }
            if (!suppressEvent) {
                me.fireEvent('change', me, item);
            }
        }
    },

<span id='Ext-button-Cycle-method-getActiveItem'>    /**
</span>     * Gets the currently active menu item.
     * @return {Ext.menu.CheckItem} The active item
     */
    getActiveItem: function() {
        return this.activeItem;
    },

    // private
    initComponent: function() {
        var me = this,
            checked = 0,
            items;

        me.addEvents(
<span id='Ext-button-Cycle-event-change'>            /**
</span>             * @event change
             * Fires after the button's active menu item has changed.  Note that if a {@link #changeHandler} function
             * is set on this CycleButton, it will be called instead on active item change and this change event will
             * not be fired.
             * @param {Ext.button.Cycle} this
             * @param {Ext.menu.CheckItem} item The menu item that was selected
             */
            &quot;change&quot;
        );

        if (me.changeHandler) {
            me.on('change', me.changeHandler, me.scope || me);
            delete me.changeHandler;
        }

        // Allow them to specify a menu config which is a standard Button config.
        // Remove direct use of &quot;items&quot; in 5.0.
        items = (me.menu.items||[]).concat(me.items||[]);
        me.menu = Ext.applyIf({
            cls: Ext.baseCSSPrefix + 'cycle-menu',
            items: []
        }, me.menu);

        // Convert all items to CheckItems
        Ext.each(items, function(item, i) {
            item = Ext.applyIf({
                group: me.id,
                itemIndex: i,
                checkHandler: me.checkHandler,
                scope: me,
                checked: item.checked || false
            }, item);
            me.menu.items.push(item);
            if (item.checked) {
                checked = i;
            }
        });
        me.itemCount = me.menu.items.length;
        me.callParent(arguments);
        me.on('click', me.toggleSelected, me);
        me.setActiveItem(checked, me);

        // If configured with a fixed width, the cycling will center a different child item's text each click. Prevent this.
        if (me.width &amp;&amp; me.showText) {
            me.addCls(Ext.baseCSSPrefix + 'cycle-fixed-width');
        }
    },

    // private
    checkHandler: function(item, pressed) {
        if (pressed) {
            this.setActiveItem(item);
        }
    },

<span id='Ext-button-Cycle-method-toggleSelected'>    /**
</span>     * This is normally called internally on button click, but can be called externally to advance the button's
     * active item programmatically to the next one in the menu.  If the current item is the last one in the menu
     * the active item will be set to the first item in the menu.
     */
    toggleSelected: function() {
        var me = this,
            m = me.menu,
            checkItem;

        checkItem = me.activeItem.next(':not([disabled])') || m.items.getAt(0);
        checkItem.setChecked(true);
    }
});</pre>
</body>
</html>
